class x_Weapons extends x_Inventory;

var name                WeaponAttachmentSocketName;

var int                 AccuracyOfWeapon;

var int                 FiringTimes;
var bool                bShouldAttachToCamera;

var float               DelayBeforeFire; //for play fire anim first

enum EWeaponType
{
	EWT_Riffle,
	EWT_Grenade,
	EWT_Handed
};
var EWeaponType         WeaponType;


/**
 * Data for the class "x_Inventory". In this class are stored temporarily
 * until the completion of the new architecture.
 * */
/** DB object*/
var xDB_Info_InventoryItem mInventoryItem;
/** DB item name*/
var string mItemName;

/** Max ammo count */
var int MaxAmmoCount;
//var int AmmoCount;

/** Holds the amount of ammo used for a given shot */
var array<int> ShotCost;

/** Offset from view center */
var(FirstPerson) vector	PlayerViewOffset;

/*********************************************************************************************
 Animations and Sounds
********************************************************************************************* */
var bool bSuppressSounds;

/** Animation to play when the weapon is fired */
var(Animations)	array<name>	WeaponFireAnim;

/** Animation to play when the weapon is Put Down */
var(Animations) name	WeaponPutDownAnim;

/** Animation to play when the weapon is Equipped */
var(Animations) name	WeaponEquipAnim;

var(Animations) array<name> WeaponIdleAnims;

/** Sound to play when the weapon is fired */
var(Sounds)	array<SoundCue>	WeaponFireSnd;

/** Sound to play when the weapon is Put Down */
var(Sounds) SoundCue 	WeaponPutDownSnd;

/** Sound to play when the weapon is Equipped */
var(Sounds) SoundCue 	WeaponEquipSnd;

/*********************************************************************************************
 Muzzle Flash
********************************************************************************************* */

/** Holds the name of the socket to attach a muzzle flash too */
var name					MuzzleFlashSocket;

/** Muzzle flash PSC and Templates*/
var ParticleSystemComponent	MuzzleFlashPSC;

/** Array of Particle Systems for our firemodes */
var array<ParticleSystem>			MuzzleFlashPSCTemplate;

/** How long the Muzzle Flash should be there */
var() float					MuzzleFlashDuration;

/** Whether muzzleflash has been initialized */
var bool					bMuzzleFlashAttached;

/** dynamic light */
var class<UDKExplosionLight> MuzzleFlashLightClass;
var	UDKExplosionLight		MuzzleFlashLight;

/*********************************************************************************************
Replication
**********************************************************************************************/
simulated event ReplicatedEvent(name VarName)
{
	if ( VarName == 'AmmoCount' )
	{
		if ( !HasAnyAmmo() )
		{
			WeaponEmpty();
		}
	}
	else
	{
		Super.ReplicatedEvent(VarName);
	}
}

client reliable simulated function ClientEndFire(byte FireModeNum)
{
	if (Role != ROLE_Authority)
	{
		ClearPendingFire(FireModeNum);
		EndFire(FireModeNum);
	}
}

/*********************************************************************************************
Functions
**********************************************************************************************/
function xDB_Info_InventoryItem SetDBObject( xDB_Info_InventoryItem lItem )
{
	mInventoryItem = lItem;
	return mInventoryItem;
}

function xDB_Info_InventoryItem GetDBObject()
{
	return mInventoryItem;
}

simulated function AttachWeaponTo( SkeletalMeshComponent MeshCpnt, optional Name aSocketName )
{
	local x_Pawn P;
	local name lSocketNameAttachTo;

	P = x_Pawn(Instigator);

	if (P != none)
	{
		Mesh.SetShadowParent(P.Mesh); //and the shadows

		if(aSocketName != '') lSocketNameAttachTo = aSocketName;
			else 
				if (WeaponAttachmentSocketName != '') lSocketNameAttachTo = WeaponAttachmentSocketName;
					else lSocketNameAttachTo = P.WeaponSocket;

		SetBase(P,,P.Mesh, lSocketNameAttachTo);
		P.Mesh.AttachComponentToSocket(Mesh, lSocketNameAttachTo);

		if (OverlayMesh != none)
		{
			P.Mesh.AttachComponentToSocket(OverlayMesh, lSocketNameAttachTo);
		}
	}

	SetHidden(false);
}

simulated function CreateOverlayMesh()
{
	if (WorldInfo.NetMode != NM_DedicatedServer)
	{
		OverlayMesh = new(self) Mesh.Class;
		OverlayMesh.SetScale(1.05);
		SkeletalMeshComponent(OverlayMesh).SetSkeletalMesh(SkeletalMeshComponent(Mesh).SkeletalMesh);
		OverlayMesh.SetOwnerNoSee(false);
		OverlayMesh.SetOnlyOwnerSee(false);
		SkeletalMeshComponent(OverlayMesh).AnimSets = SkeletalMeshComponent(Mesh).AnimSets;
		SkeletalMeshComponent(OverlayMesh).SetParentAnimComponent(SkeletalMeshComponent(Mesh));
		SkeletalMeshComponent(OverlayMesh).bUpdateSkelWhenNotRendered = false;
		SkeletalMeshComponent(OverlayMesh).bIgnoreControllersWhenNotRendered = true;
		SkeletalMeshComponent(OverlayMesh).bOverrideAttachmentOwnerVisibility = true;

		if (UDKSkeletalMeshComponent(OverlayMesh) != none)
		{
			UDKSkeletalMeshComponent(OverlayMesh).SetFOV(UDKSkeletalMeshComponent(Mesh).FOV);
		}
	}
}

/**
 * Apply a given overlay material to the overlay mesh.
 */
simulated function SetOverlayMaterial(MaterialInterface NewOverlay)
{	
	local int i;

	if (OverlayMesh == None)
	{
		CreateOverlayMesh();
	}
	for (i=0; i < OverlayMesh.GetNumElements(); i++)
	{
		OverlayMesh.SetMaterial(i, NewOverlay);
	}
	if (!OverlayMesh.bAttached)
	{
		AttachComponent(OverlayMesh);
	}
}

function bool isOverlayAttached()
{
	return OverlayMesh.bAttached;
}

simulated function ReattachWeaponMesh()
{
	DetachComponent(Mesh);
	AttachComponent(Mesh);
}

/**
 * Detach weapon from skeletal mesh
 */
simulated function DetachFrom( SkeletalMeshComponent MeshCpnt )
{
	// Weapon Mesh Shadow
	if ( Mesh != None )
	{
		Mesh.SetShadowParent(None);
		Mesh.SetLightEnvironment(None);
		// muzzle flash effects
		if (MuzzleFlashPSC != None)
		{
			SkeletalMeshComponent(Mesh).DetachComponent(MuzzleFlashPSC);
		}
		if (MuzzleFlashLight != None)
		{
			SkeletalMeshComponent(Mesh).DetachComponent(MuzzleFlashLight);
		}
	}
	if ( MeshCpnt != None )
	{
		// detach weapon mesh from player skelmesh
		if ( Mesh != None )
		{
			MeshCpnt.DetachComponent( mesh );
		}

		if ( OverlayMesh != none )
		{
			MeshCpnt.DetachComponent( OverlayMesh );
		}
	}

	GotoState('');
}

simulated function DetachOverlayMesh()
{
	//OverlayMesh.SetHidden(true); //hide the weapon when inactive
	OverlayMesh.SetShadowParent(none); //just in case
	//Instigator.Mesh.DetachComponent(OverlayMesh); //might as well, saves us a transform
	DetachComponent(OverlayMesh); //might as well, saves us a transform
}

simulated function DetachWeapon()
{
	super.DetachWeapon();
	SetHidden(true); //hide the weapon when inactive
	Mesh.SetShadowParent(none); //just in case
	Instigator.Mesh.DetachComponent(Mesh); //might as well, saves us a transform
}

/** Pull out & ready the weapon */
simulated function Activate()
{
	super.Activate();
	AttachWeaponTo(Instigator.Mesh,WeaponAttachmentSocketName);
}

/** Hide the weapon */
simulated function PutDownWeapon()
{
	super.PutDownWeapon();
	DetachWeapon();
}

/**
 * Show the weapon being put away
 */
simulated function PlayWeaponPutDown()
{
	// Play the animation for the weapon being put down

	if ( WeaponPutDownAnim != '' )
		PlayWeaponAnimation( WeaponPutDownAnim, PutDownTime );

	// play any associated sound
	if ( WeaponPutDownSnd != None )
		WeaponPlaySound( WeaponPutDownSnd );
}

simulated event SetPosition(UDKPawn Holder)
{
	local vector DrawOffset, ViewOffset, FinalLocation;
	local rotator NewRotation, FinalRotation, SpecRotation;
	local PlayerController PC;
	local vector2D ViewportSize;
	local bool bIsWideScreen;
	local vector SpecViewLoc;

	if ( !Holder.IsFirstPerson() )
		return;

	Mesh.SetHidden(False);

	foreach LocalPlayerControllers(class'PlayerController', PC)
	{
		LocalPlayer(PC.Player).ViewportClient.GetViewportSize(ViewportSize);
		break;
	}
	bIsWideScreen = (ViewportSize.Y > 0.f) && (ViewportSize.X/ViewportSize.Y > 1.7);

	Mesh.SetScale3D(default.Mesh.Scale3D);
	Mesh.SetRotation(default.Mesh.Rotation);

	ViewOffset = PlayerViewOffset;

	// Calculate the draw offset
	if ( Holder.Controller == None )
	{
		PC.GetPlayerViewPoint(SpecViewLoc, SpecRotation);
		DrawOffset = ViewOffset >> SpecRotation;
		//DrawOffset += UTPawn(Holder).WeaponBob(BobDamping, JumpDamping);
		FinalLocation = SpecViewLoc + DrawOffset;
		SetLocation(FinalLocation);
		SetBase(Holder);

		// Add some rotation leading
		//SpecRotation.Yaw = LagRot(SpecRotation.Yaw & 65535, LastRotation.Yaw & 65535, MaxYawLag, 0);
		//SpecRotation.Pitch = LagRot(SpecRotation.Pitch & 65535, LastRotation.Pitch & 65535, MaxPitchLag, 1);
		//LastRotUpdate = WorldInfo.TimeSeconds;
		//LastRotation = SpecRotation;

		if ( bIsWideScreen )
		{
			//SpecRotation += WidescreenRotationOffset;
		}
		SetRotation(SpecRotation);
		return;
	}
	else
	{

		//DrawOffset.Z = X_COM_Pawn(Holder).GetEyeHeight();

		//DrawOffset += X_COM_Pawn(Holder).WeaponBob(BobDamping, JumpDamping);
		/*
		if ( xcT_AIController(Holder.Controller) != None )
		{
			DrawOffset += xcT_AIController(Holder.Controller).ShakeOffset >> Holder.Controller.Rotation;
		}
		*/
		DrawOffset = DrawOffset + ( ViewOffset >> Holder.Controller.Rotation );
	}

	// Adjust it in the world
	FinalLocation = Holder.Location + DrawOffset;
	SetLocation(FinalLocation);
	SetBase(Holder);

	NewRotation = (Holder.Controller == None) ? Holder.GetBaseAimRotation() : Holder.Controller.Rotation;

	// Add some rotation leading
	//if (Holder.Controller != None)
	//{
	//	FinalRotation.Yaw = LagRot(NewRotation.Yaw & 65535, LastRotation.Yaw & 65535, MaxYawLag, 0);
	//	FinalRotation.Pitch = LagRot(NewRotation.Pitch & 65535, LastRotation.Pitch & 65535, MaxPitchLag, 1);
	//	FinalRotation.Roll = NewRotation.Roll;
	//}
	//else
	//{
		FinalRotation = NewRotation;
	//}
	//LastRotUpdate = WorldInfo.TimeSeconds;
	//LastRotation = NewRotation;

	if ( bIsWideScreen )
	{
		//FinalRotation += WidescreenRotationOffset;
	}
	SetRotation(FinalRotation);
}

/**
 * Tells the weapon to play a firing sound (uses CurrentFireMode)
 */
simulated function PlayFiringSound()
{
	if (CurrentFireMode<WeaponFireSnd.Length)
	{
		// play weapon fire sound
		if ( WeaponFireSnd[CurrentFireMode] != None )
		{
			MakeNoise(1.0);
			WeaponPlaySound( WeaponFireSnd[CurrentFireMode] );
		}
	}
}

/**
 * This function handles playing sounds for weapons.  How it plays the sound depends on the following:
 *
 * If we are a listen server, then this sound is played and replicated as normal
 * If we are a remote client, but locally controlled (ie: we are on the client) we play the sound and don't replicate it
 * If we are a dedicated server, play the sound and replicate it to everyone BUT the owner (he will play it locally).
 *
 *
 * @param	Sound	- The Source Cue to play
 */
simulated function WeaponPlaySound(SoundCue Sound, optional float NoiseLoudness)
{
	// if we are a listen server, just play the sound.  It will play locally
	// and be replicated to all other clients.
	if( Sound != None && Instigator != None && !bSuppressSounds  )
	{
		Instigator.PlaySound(Sound, false, true);
	}
}


/*********************************************************************************************
 * State Active
 * 
 *********************************************************************************************/
simulated state Active
{

	simulated event OnAnimEnd(optional AnimNodeSequence SeqNode, optional float PlayedTime, optional float ExcessTime)
	{
		local int IdleIndex;

		if ( WorldInfo.NetMode != NM_DedicatedServer && WeaponIdleAnims.Length > 0 )
		{
			IdleIndex = Rand(WeaponIdleAnims.Length);
			PlayWeaponAnimation(WeaponIdleAnims[IdleIndex], 0.0, true);
		}
	}

	simulated function PlayWeaponAnimation( Name Sequence, float fDesiredDuration, optional bool bLoop, optional SkeletalMeshComponent SkelMesh)
	{
		Global.PlayWeaponAnimation(Sequence, fDesiredDuration,bLoop,SkelMesh);
		ClearTimer('OnAnimEnd');
		if (!bLoop)
		{
			SetTimer(fDesiredDuration,false,'OnAnimEnd');
		}
	}

	simulated function bool ShouldLagRot()
	{
		return true;
	}

	/** Initialize the weapon as being active and ready to go. */
	simulated function BeginState( Name PreviousStateName )
	{
		OnAnimEnd(none, 0.f, 0.f);

		Super.BeginState(PreviousStateName);

		if (InvManager != none && InvManager.LastAttemptedSwitchToWeapon != none)
		{
			if (InvManager.LastAttemptedSwitchToWeapon != self)
			{
				InvManager.LastAttemptedSwitchToWeapon.ClientWeaponSet(true);
			}
			InvManager.LastAttemptedSwitchToWeapon = none;
		}
	}
}

/*********************************************************************************************
 * State WeaponEquipping
 * 
 *********************************************************************************************/
simulated state WeaponEquipping
{
	simulated event BeginState(Name PreviousStateName)
	{
        AttachWeaponTo(Instigator.Mesh);
		Super.BeginState(PreviousStateName);
	}
}

/**
 * Show the weapon begin equipped
 */
simulated function PlayWeaponEquip()
{
	// Play the animation for the weapon being put down

	if ( WeaponEquipAnim != '' )
		PlayWeaponAnimation( WeaponEquipAnim, EquipTime );

	// play any assoicated sound
	if ( WeaponEquipSnd != None )
		WeaponPlaySound( WeaponEquipSnd );
}

/*********************************************************************************************
 * State WeaponFiring
 * This is the default Firing State.  It's performed on both the client and the server.
 *********************************************************************************************/
simulated state WeaponFiring
{
	simulated event ReplicatedEvent(name VarName)
	{
		if ( VarName == 'AmmoCount' && !HasAnyAmmo() )
		{
			return;
		}

		Global.ReplicatedEvent(VarName);
	}

	/**
	 * We override BeginFire() so that we can check for zooming and/or empty weapons
	 */
	simulated function BeginFire( Byte FireModeNum )
	{
		Global.BeginFire(FireModeNum);

		// No Ammo, then do a quick exit.
		if( !HasAmmo(FireModeNum) )
		{
			WeaponEmpty();
			return;
		}
	}

	/**
	 * When we are in the firing state, don't allow for a pickup to switch the weapon
	 */
	simulated function bool DenyClientWeaponSet()
	{
		return true;
	}

	simulated event BeginState( Name PreviousStateName ) // UNUSED. functions moved to begin: label
	{
		// Play Weapon fire animation
		if ( CurrentFireMode < WeaponFireAnim.Length && WeaponFireAnim[CurrentFireMode] != '' )
		{
			PlayWeaponAnimation( WeaponFireAnim[CurrentFireMode], GetFireInterval(CurrentFireMode));
		}
	}



Begin:
	Sleep(DelayBeforeFire);                                         // start fire anim
	FireAmmunition();                                               // do fire
	Sleep(GetFireInterval(CurrentFireMode) - DelayBeforeFire);      // end fire anim
	HandleFinishedFiring();                                         // end fire
}

simulated function FireAmmunition()
{
	// Use ammunition to fire
	ConsumeAmmo( CurrentFireMode );

	// if this is the local player, play the firing effects
	PlayFiringSound();

	// Handle the different fire types
	switch( WeaponFireTypes[CurrentFireMode] )
	{
		case EWFT_InstantHit:   InstantFire();
		break;

		case EWFT_Projectile:   ProjectileFire();
		break;

		case EWFT_Custom:       CustomFire();
		break;
	}

	NotifyWeaponFired( CurrentFireMode );
}

/*********************************************************************************************
 Muzzle Flash Methods
**********************************************************************************************/
/**
 * PlayFireEffects Is the root function that handles all of the effects associated with
 * a weapon.  This function creates the 1st person effects.  It should only be called
 * on a locally controlled player.
 */
simulated function PlayFireEffects( byte FireModeNum, optional vector HitLocation )
{
	// Start muzzle flash effect
	CauseMuzzleFlash();
}

simulated function StopFireEffects(byte FireModeNum)
{
	StopMuzzleFlash();
}

simulated function PlayWeaponAnimation(name Sequence, float fDesiredDuration, optional bool bLoop, optional SkeletalMeshComponent SkelMesh)
{
	if (Mesh != None && Mesh.bAttached)
	{
		Super.PlayWeaponAnimation(Sequence, fDesiredDuration, bLoop, SkelMesh);
	}
}

/**
 * Called on a client, this function Attaches the MuzzleFlashParticleSystemComponent
 */
function AttachMuzzleFlash()
{
	local SkeletalMeshComponent SKMesh;

	// Attach the Muzzle Flash
	bMuzzleFlashAttached = true;
	SKMesh = SkeletalMeshComponent(Mesh);
	if (  SKMesh != none )
	{
	    //if our weapon has at least one muzzle flash
	    //lets attach our muzzle flash particle system component
		if ( MuzzleFlashPSCTemplate.Length > 0 )
		{
			MuzzleFlashPSC = new(Outer)class'ParticleSystemComponent';
			MuzzleFlashPSC.bAutoActivate = false;
			//MuzzleFlashPSC.SetDepthPriorityGroup(SDPG_Foreground);
			MuzzleFlashPSC.SetOwnerNoSee(true);
			//MuzzleFlashPSC.SetFOV(UDKSkeletalMeshComponent(SKMesh).FOV);
			SKMesh.AttachComponentToSocket(MuzzleFlashPSC, MuzzleFlashSocket);
		}
	}
}

/**
 * Causes the muzzle flash to turn on and setup a time to
 * turn it back off again.
 */
event CauseMuzzleFlash()
{
	local ParticleSystem MuzzleTemplate;

	// only enable muzzleflash light if performance is high enough
	// enable muzzleflash on mobile since its one of the few ways to show dynamic lighting on skelmeshes
	if ((!WorldInfo.bDropDetail && !class'Engine'.static.IsSplitScreen()) || WorldInfo.IsConsoleBuild(CONSOLE_Mobile) )
	{
		if ( MuzzleFlashLight == None )
		{
			if ( MuzzleFlashLightClass != None )
			{
				MuzzleFlashLight = new(Outer) MuzzleFlashLightClass;
				if (Mesh != None && SkeletalMeshComponent(Mesh).GetSocketByName(MuzzleFlashSocket) != None)
				{
					SkeletalMeshComponent(Mesh).AttachComponentToSocket(MuzzleFlashLight, MuzzleFlashSocket);
				}
			}
		}
		else
		{
			MuzzleFlashLight.ResetLight();
		}
	}

    //Only proceed if our firing mode has a muzzle flash
	if (Instigator.FiringMode < MuzzleFlashPSCTemplate.Length)
	{
		if ( !bMuzzleFlashAttached )
		{
			AttachMuzzleFlash();
		}
		if (MuzzleFlashPSCTemplate[Instigator.FiringMode] != None)
		{
			if (!MuzzleFlashPSC.bIsActive || MuzzleFlashPSC.bWasDeactivated)
			{
				MuzzleTemplate = MuzzleFlashPSCTemplate[Instigator.FiringMode];

				//If our current PSC is using a different muzzle flash particle
				//Lets go ahead and swap it with the one we need
				if (MuzzleTemplate != MuzzleFlashPSC.Template)
				{
					MuzzleFlashPSC.SetTemplate(MuzzleTemplate);
				}
				SetMuzzleFlashParams(MuzzleFlashPSC);
				MuzzleFlashPSC.ActivateSystem();
			}
		}
		// Set when to turn it off.
		SetTimer(MuzzleFlashDuration,false,'MuzzleFlashTimer');
	}
}

/**
 * Turns the MuzzleFlashPSC off
 */
event MuzzleFlashTimer()
{
	if ( MuzzleFlashLight != None )
	{
		MuzzleFlashLight.SetEnabled(FALSE);
	}

	if (MuzzleFlashPSC != none)
	{
		MuzzleFlashPSC.DeactivateSystem();
	}
}

event StopMuzzleFlash()
{
	ClearTimer('MuzzleFlashTimer');
	MuzzleFlashTimer();

	if ( MuzzleFlashPSC != none )
	{
		MuzzleFlashPSC.DeactivateSystem();
	}
}

/**
 * Allows a child to setup custom parameters on the muzzle flash
 */

function SetMuzzleFlashParams(ParticleSystemComponent PSC)
{
	return;
}


/*********************************************************************************************
 * Ammunition / Inventory
 *********************************************************************************************/
function int GetAmmoCount()
{
	return AmmoCount;
}
 /*
 * Consumes some of the ammo
 */
function ConsumeAmmo( byte FireModeNum )
{
	// Subtract the Ammo
	AddAmmo(-ShotCost[FireModeNum]);
}

/**
 * This function is used to add ammo back to a weapon.  It's called from the Inventory Manager
 */
function int AddAmmo( int Amount )
{
	AmmoCount = Clamp(AmmoCount + Amount,0,MaxAmmoCount);
	return AmmoCount;
}


/**
 * Returns true if the ammo is maxed out
 */
function bool AmmoMaxed(int mode)
{
	return (AmmoCount >= MaxAmmoCount);
}

/**
 * This function checks to see if the weapon has any ammo available for a given fire mode.
 *
 * @param	FireModeNum		- The Fire Mode to Test For
 * @param	Amount			- [Optional] Check to see if this amount is available.  If 0 it will default to checking
 *							  for the ShotCost
 */
simulated function bool HasAmmo( byte FireModeNum, optional int Amount )
{
	if (Amount==0)
		return (AmmoCount >= ShotCost[FireModeNum]);
	else
		return ( AmmoCount >= Amount );
}

/**
 * returns true if this weapon has any ammo
 */
simulated function bool HasAnyAmmo()
{
	return ( ( AmmoCount > 0 ) || (ShotCost[0]==0 && ShotCost[1]==0) );
}

/**
 * This function retuns how much of the clip is empty.
 */
function float DesireAmmo(bool bDetour)
{
	return (1.f - float(AmmoCount)/MaxAmmoCount);
}

/**
 * Returns true if the current ammo count is less than the default ammo count
 */
function bool NeedAmmo()
{
	return ( AmmoCount < Default.AmmoCount );
}

/**
 * Cheat Help function the loads out the weapon
 *
 * @param 	bUseWeaponMax 	- [Optional] If true, this function will load out the weapon
 *							  with the actual maximum, not 999
 */
function Loaded(optional bool bUseWeaponMax)
{
	if (bUseWeaponMax)
		AmmoCount = MaxAmmoCount;
	else
		AmmoCount = 999;
}

/**
 * Called when the weapon runs out of ammo during firing
 */
simulated function WeaponEmpty()
{
	// If we were firing, stop
	if ( IsFiring() )
	{
		GotoState('Active');
	}

	if ( Instigator != none && Instigator.IsLocallyControlled() )
	{
		Instigator.InvManager.SwitchToBestWeapon( true );
	}
}

/*********************************************************************************************
 * Fire Fucntions
 *********************************************************************************************/
/**
 * Fires a projectile.
 * Spawns the projectile, but also increment the flash count for remote client effects.
 * Network: Local Player and Server
 */
simulated function Projectile ProjectileFire()
{
	local vector		RealStartLoc;
	local Projectile	SpawnedProjectile;

	// tell remote clients that we fired, to trigger effects
	IncrementFlashCount();

	if( Role == ROLE_Authority )
	{
		// this is the location where the projectile is spawned.
		RealStartLoc = GetPhysicalFireStartLoc();

		// Spawn projectile
		SpawnedProjectile = Spawn(GetProjectileClass(),,, RealStartLoc);
		if( SpawnedProjectile != None && !SpawnedProjectile.bDeleteMe )
		{
			SpawnedProjectile.Init( Vector(GetAdjustedAim( RealStartLoc )) );
		}

		// Return it up the line
		return SpawnedProjectile;
	}

	return None;
}

DefaultProperties
{
	Begin Object Class=UDKSkeletalMeshComponent Name=SkeletalMeshComponent0
		CollideActors=false
		AlwaysLoadOnClient=true
		AlwaysLoadOnServer=true
		MaxDrawDistance=10000
		bUseAsOccluder=FALSE
		bUpdateSkelWhenNotRendered=false
		bIgnoreControllersWhenNotRendered=true
		bOverrideAttachmentOwnerVisibility=true
		bAcceptsDynamicDecals=FALSE
	End Object
	Components.Add(SkeletalMeshComponent0)
	Mesh=SkeletalMeshComponent0
	WeaponAttachmentSocketName=Right_HandWeapon

	FiringStatesArray(0)=WeaponFiring
	//FiringStatesArray(1)=WeaponFiring

	//InstantHitDamageTypes(0)=class'DamageType'
	//InstantHitDamageTypes(1)=class'DamageType'

	ShouldFireOnRelease(0)=0
	//ShouldFireOnRelease(1)=0

	FireInterval(0)=0

	EquipTime=+0.45
	PutDownTime=+0.33

	WeaponPutDownAnim=WeaponPutDown
	WeaponEquipAnim=WeaponEquip
	WeaponIdleAnims(0)=WeaponIdle
	WeaponFireAnim(0)=WeaponFire
	WeaponFireAnim(1)=WeaponFire
	DefaultAnimSpeed=0.9
}